//
//  DTagAnalysisViewController.swift
//  Drop
//
//  Created by hushaohua on 2018/2/25.
//  Copyright © 2018年 init. All rights reserved.
//

import UIKit
import CoreData

class DTagAnalysisViewController: UITableViewController {

    convenience init(tag:DTagAnalysisItem){
        self.init(style: .plain);
        self.tagAnalysis = tag;
    }
    
    override init(style: UITableViewStyle) {
        
        self.analysisPref = DAnalysisDatePreference();
        self.analysisPref.intervalType = .Day;
        self.analysisPref.intervalValue.subType = .All;
        super.init(style: style);
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        self.view.backgroundColor = UIColor.white;
        self.configTableView();
        self.configNavigationItem();
        
        self.requestNewest();
    }
    
    var tagAnalysis:DTagAnalysisItem?;
    
    func configNavigationItem() -> Void{
        let button = UIBarButtonItem(customView: self.filterButton());
        self.navigationItem.rightBarButtonItem = button;
        self.navigationItem.titleView = self.titleView();
        self.subTitleLabel.text = self.analysisPref.analysisDescription();
    }
    
    func filterButton() -> UIButton{
        let button = UIButton(frame: CGRect(x:0,y:0,width:44,height:44));
        button.contentHorizontalAlignment = .right;
        button.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .light);
        button.setTitle("设置", for: .normal);
        button.setTitleColor(UIColor.darkGray, for: .normal);
        button.addTarget(self, action: #selector(changeDate), for: .touchUpInside);
        return button;
    }
    
    func titleView() -> UIView{
        let view = UIView(frame: CGRect(x:0,y:0,width:200,height:44));
        view.addSubview(self.titleLabel());
        view.addSubview(self.subTitleLabel);
        return view;
    }
    
    func titleLabel() -> UILabel{
        let label:UILabel = UILabel(frame: CGRect(x:0,y:6,width:200,height:24));
        label.autoresizingMask = [.flexibleWidth];
        label.text = self.tagAnalysis?.tagName;
        label.font = UIFont.systemFont(ofSize: 18);
        label.textAlignment = .center;
        label.textColor = UIColor.black;
        return label;
    }
    
    lazy var subTitleLabel:UILabel = {
        var label:UILabel = UILabel(frame: CGRect(x:0,y:30,width:200,height:12));
        label.autoresizingMask = [.flexibleWidth];
        label.text = "所有";
        label.font = UIFont.systemFont(ofSize: 10, weight: .light);
        label.textAlignment = .center;
        label.textColor = UIColor.gray;
        return label;
    }();
    
    var analysisPref:DAnalysisDatePreference;
    @objc func changeDate() -> Void{
        let controller = DAnalysisDatePreferenceViewController();
        controller.analysis = self.analysisPref.copy();
        controller.doneClosure = { (analysis) in
            self.analysisPref = analysis;
            self.requestNewest();
            self.subTitleLabel.text = analysis.analysisDescription();
            self.navigationController?.popViewController(animated: true);
        };
        self.navigationController?.pushViewController(controller, animated: true);
    }
    
    lazy var tableHeaderView:UIView = {
        let view:UIView = UIView(frame: CGRect(x:0,y:0,width:self.view.bounds.size.width,height:100 + 10));
        view.addSubview(self.chartHeaderView);
        return view;
    }();
    
    lazy var chartHeaderView:HLineChartView = {
        var view:HLineChartView = HLineChartView(frame: CGRect(x:10,y:10,width:self.view.bounds.size.width - 20,height:100));
        view.disableKeyTexts = true;
        view.lineConfig().keyAxisPref?.lineColor = UIColor.lightGray;
        view.lineConfig().valueAxisPref?.lineColor = UIColor.lightGray;
        view.backgroundColor = UIColor.white;
        return view;
    }();
    
    func configTableView() -> Void{
        self.tableView.tableHeaderView = self.tableHeaderView;
        self.tableView.tableFooterView = UIView();
        self.tableView.contentInset = UIEdgeInsets(top:0,left:0,bottom:84,right:0);
        self.tableView.rowHeight = 44;
        self.tableView.sectionHeaderHeight = 32;
        self.tableView.register(DAnalysisTagTableViewCell.self, forCellReuseIdentifier: "Cell");
        self.tableView.register(DAnalysisTitleHeaderView.self, forHeaderFooterViewReuseIdentifier: "Header");
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    var analysisItems:[DTagDateAnalysisItem] = [DTagDateAnalysisItem]();
    func requestNewest() -> Void{
        if (self.tagAnalysis == nil){
            return;
        }
        self.configTagsRequest();
        do{
            let tags = try HStoreManager.defaultManger().context.fetch(self.tagsRequest);
            self.analysisItems.removeAll();
            for dict in tags {
                let interval:Int64 = dict.object(forKey: "intervals") as! Int64;
                let tag:DTagDateAnalysisItem = DTagDateAnalysisItem();
                self.analysisItems.append(tag);
                tag.duration = interval;
                tag.count = dict.object(forKey: "count") as! Int32;
                var beginEndDates:(begin:Date, end:Date)? = nil;
                switch self.analysisPref.intervalType {
                case .Day:
                    let year = dict.object(forKey: "year") as! Int32;
                    let month = dict.object(forKey: "month") as! Int16;
                    let day = dict.object(forKey: "day") as! Int16;
                    beginEndDates = Date.dayBeginToEndDates(Int(year), month: Int(month), day: Int(day));
                    tag.dateString = "\(year)-\(month)-\(day)";
                case .Week:
                    let year = dict.object(forKey: "yearForWeek") as! Int32;
                    let week = dict.object(forKey: "weekOfYear") as! Int16;
                    beginEndDates = Date.weekBeginToEndDates(Int(week), yearForWeek: Int(year));
                    tag.dateString = "\(beginEndDates!.begin.defaultDateString())->\(beginEndDates!.end.defaultDateString())";
                case .Month:
                    let year = dict.object(forKey: "year") as! Int32;
                    let month = dict.object(forKey: "month") as! Int16;
                    beginEndDates = Date.monthBeginToEndDates(Int(year), month: Int(month));
                    tag.dateString = "\(year)年\(month)月";
                }
                tag.beginDate = beginEndDates?.begin;
                tag.endDate = beginEndDates?.end;
            }
            self.setChartHeaderItems();
            self.tableView.reloadData();
        }catch{
            let nserror = error as NSError
            fatalError("tags controller fetch error \(nserror), \(nserror.userInfo)")
        }
    }
    
    func setChartHeaderItems() -> Void{
        var chartItems:[HLineChartItem] = [HLineChartItem]();
        var index:Int = self.analysisItems.count - 1;
        var latestDate:Date? = nil;
        let calendar:Calendar = Calendar.current;
        while index >= 0 {
            let item:DTagDateAnalysisItem = self.analysisItems[index];
            if (latestDate != nil){
                let components = calendar.dateComponents([.year, .month, .day], from: latestDate!, to: item.beginDate!);
                if (components.day! > 1){
                    var dayIndex:Int = 0;
                    while dayIndex < components.day! - 1 {
                        let chartItem:HLineChartItem = HLineChartItem();
                        chartItem.key = "0";
                        chartItem.value = 0;
                        chartItems.append(chartItem);
                        dayIndex = dayIndex + 1;
                    }
                }
            }
            
            let chartItem:HLineChartItem = HLineChartItem();
            chartItem.key = item.dateString;
            chartItem.value = item.duration;
            chartItems.append(chartItem);
            latestDate = item.beginDate;
            index = index - 1;
        }
        self.chartHeaderView.chartItems = chartItems;
    }
    
    func tagsRequestExpressions() -> (interval:NSExpressionDescription, count:NSExpressionDescription){
        let beginDateExp = NSExpression(forKeyPath: "begin");
        let endDateExp = NSExpression(forKeyPath: "end");
        let beginSumExpression = NSExpression(forFunction: "sum:", arguments: [beginDateExp]);
        let endSumExpression = NSExpression(forFunction: "sum:", arguments: [endDateExp]);
        let countExpression = NSExpression(forFunction: "count:", arguments:[endDateExp]);
        let intervalExp = NSExpression(forFunction: "from:subtract:", arguments: [endSumExpression, beginSumExpression]);
        
        let intervalExpDesc = NSExpressionDescription();
        intervalExpDesc.name = "intervals";
        intervalExpDesc.expression = intervalExp;
        intervalExpDesc.expressionResultType = .integer64AttributeType;
        
        let countExpDesc = NSExpressionDescription();
        countExpDesc.name = "count";
        countExpDesc.expression = countExpression;
        countExpDesc.expressionResultType = .integer32AttributeType;
        
        return (intervalExpDesc, countExpDesc);
    }
    
    func configTagsRequest() -> Void{
        let expressions = self.tagsRequestExpressions();
        switch self.analysisPref.intervalType {
        case .Day:
            self.tagsRequest.propertiesToFetch = ["year", "month", "day", expressions.interval, expressions.count];
            self.tagsRequest.propertiesToGroupBy = ["year", "month", "day"];
            self.tagsRequest.sortDescriptors = [
                NSSortDescriptor(key: "year", ascending: false),
                NSSortDescriptor(key: "month", ascending: false),
                NSSortDescriptor(key: "day", ascending: false)
            ];
        case .Month:
            self.tagsRequest.propertiesToFetch = ["year", "month", expressions.interval, expressions.count];
            self.tagsRequest.propertiesToGroupBy = ["year", "month"];
            self.tagsRequest.sortDescriptors = [
                NSSortDescriptor(key: "year", ascending: false),
                NSSortDescriptor(key: "month", ascending: false)
            ];
        case .Week:
            self.tagsRequest.propertiesToFetch = ["yearForWeek", "weekOfYear", expressions.interval, expressions.count];
            self.tagsRequest.propertiesToGroupBy = ["yearForWeek", "weekOfYear"];
            self.tagsRequest.sortDescriptors = [
                NSSortDescriptor(key: "yearForWeek", ascending: false),
                NSSortDescriptor(key: "weekOfYear", ascending: false)
            ];
        }
        var predicate:NSPredicate? = nil;
        let beginDate = self.analysisPref.queryBeginDate();
        let endDate = self.analysisPref.queryEndDate();
        let tag = HStoreManager.defaultManger().context.object(with: self.tagAnalysis!.tagID!);
        if (beginDate == nil || endDate == nil){
            predicate = NSPredicate(format: "tag == %@", tag);//   在今天结束的
        }else{
            predicate = NSPredicate(format: "tag == %@ AND begin >= %@ AND begin < %@", tag, beginDate! as NSDate, endDate! as NSDate);//   在今天结束的
        }
        
        self.tagsRequest.predicate = predicate;
    }
    
    //MARK:- NSFetchedResultsController
    lazy var tagsRequest:NSFetchRequest<NSDictionary> = {
        
        let expressions = self.tagsRequestExpressions();
        
        let request:NSFetchRequest<NSDictionary> = NSFetchRequest(entityName: "Drop");
        request.resultType = .dictionaryResultType;
        request.returnsDistinctResults = true;
        request.includesSubentities = false;
        
        return request;
    }();
    
    //MARK:- tableView
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.analysisItems.count;
    }
    
    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let view:DAnalysisTitleHeaderView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "Header") as! DAnalysisTitleHeaderView;
        view.tagLabel.text = "日期";
        return view;
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell:DAnalysisTagTableViewCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! DAnalysisTagTableViewCell;
        let item:DTagDateAnalysisItem = self.analysisItems[indexPath.row];
        cell.tagLabel.text = item.dateString;
        cell.timeLabel.text = item.durationString();
        cell.accessoryType = .disclosureIndicator;
        return cell;
    }
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true);
        let controller = DTagDropViewController();
        let item:DTagDateAnalysisItem = self.analysisItems[indexPath.row];
        controller.beginDate = item.beginDate;
        controller.endDate = item.endDate;
        controller.tag = HStoreManager.defaultManger().context.object(with: self.tagAnalysis!.tagID!) as? Tag;
        self.navigationController?.pushViewController(controller, animated: true);
    }

}
